#!/usr/bin/env python3
#
# Call with pytest. Requires XKB_CONFIG_ROOT to be set

import os
import subprocess
import sys
from pathlib import Path

import pytest


def _xkb_config_root():
    path = os.getenv("XKB_CONFIG_ROOT")
    assert path is not None, "Environment variable XKB_CONFIG_ROOT must be set"
    print(f"Using {path}")

    xkbpath = Path(path)
    assert (xkbpath / "symbols").exists(), f"{path} is not an XKB installation"
    return xkbpath


@pytest.fixture
def xkb_config_root():
    return _xkb_config_root()


def pytest_generate_tests(metafunc):
    # for any test_foo function with an argument named xkb_symbols,
    # make it a list of tuples in the form (us, dvorak)
    # The list is generated by scanning all xkb symbol files and extracting the
    # various sections
    if "xkb_symbols" in metafunc.fixturenames:
        xkb_symbols = []
        # This skips the *_vndr directories, they're harder to test
        for symbols_file in _xkb_config_root().glob("symbols/*"):
            if symbols_file.is_dir():
                continue
            with open(symbols_file) as f:
                print(f"Found file {symbols_file}")
                for line in f:
                    if not line.startswith('xkb_symbols "'):
                        continue
                    section = line.split('"')[1]
                    xkb_symbols.append((symbols_file.name, section))
        assert xkb_symbols
        metafunc.parametrize("xkb_symbols", xkb_symbols)


def test_xkbcomp(xkb_config_root, xkb_symbols):
    layout, variant = xkb_symbols
    keymap = f"""
xkb_keymap {{
        xkb_keycodes  {{ include "evdev+aliases(qwerty)" }};
        xkb_types     {{ include "complete"      }};
        xkb_compat    {{ include "complete"      }};
        xkb_symbols   {{ include "pc+{layout}({variant})"     }};
}};
"""
    print(keymap)

    args = [
        "xkbcomp",
        "-w0",  # reduce warning nose
        "-xkb",
        "-I",  # disable system includes
        f"-I{xkb_config_root}",
        "-",
        "-",  # from stdin, to stdout
    ]
    p = subprocess.run(args, input=keymap, encoding="utf-8", capture_output=True)
    if p.stderr:
        print(p.stderr, file=sys.stderr)
    if p.returncode != 0:
        print(p.stdout)
    if p.returncode < 0:
        print(f"xkbcomp exited with signal {-p.returncode}", file=sys.stderr)

    assert p.returncode == 0
